package com.powerbank.user.controller;

import com.powerbank.common.result.Result;
import com.powerbank.common.utils.JwtUtils;
import com.powerbank.user.dto.CreatePaymentDTO;
import com.powerbank.user.service.PaymentService;
import com.powerbank.user.vo.PaymentResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import java.math.BigDecimal;

/**
 * 支付控制器
 */
@Slf4j
@RestController
@RequestMapping("/payment")
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private JwtUtils jwtUtils;

    /**
     * 创建支付订单
     */
    @PostMapping("/create")
    public Result<PaymentResultVO> createPayment(@RequestBody @Valid CreatePaymentDTO paymentDTO,
                                                 HttpServletRequest request) {
        Long userId = getUserIdFromToken(request);
        
        // 设置客户端IP
        paymentDTO.setClientIp(getClientIpAddress(request));
        
        try {
            PaymentResultVO result = paymentService.createPayment(userId, paymentDTO);
            return Result.success("支付订单创建成功", result);
        } catch (Exception e) {
            log.error("创建支付订单失败：{}", e.getMessage(), e);
            return Result.error("创建支付订单失败：" + e.getMessage());
        }
    }

    /**
     * 查询支付状态
     */
    @GetMapping("/status/{paymentNo}")
    public Result<PaymentResultVO> queryPaymentStatus(@PathVariable @NotBlank(message = "支付流水号不能为空") String paymentNo) {
        try {
            PaymentResultVO result = paymentService.queryPaymentStatus(paymentNo);
            return Result.success("支付状态查询成功", result);
        } catch (Exception e) {
            log.error("查询支付状态失败：{}", e.getMessage(), e);
            return Result.error("查询支付状态失败：" + e.getMessage());
        }
    }

    /**
     * 取消支付
     */
    @PostMapping("/cancel/{paymentNo}")
    public Result<Void> cancelPayment(@PathVariable @NotBlank(message = "支付流水号不能为空") String paymentNo,
                                      HttpServletRequest request) {
        Long userId = getUserIdFromToken(request);
        
        try {
            boolean success = paymentService.cancelPayment(userId, paymentNo);
            return success ? Result.success("支付已取消", (Void) null) : Result.error("取消支付失败");
        } catch (Exception e) {
            log.error("取消支付失败：{}", e.getMessage(), e);
            return Result.error("取消支付失败：" + e.getMessage());
        }
    }

    /**
     * 申请退款
     */
    @PostMapping("/refund/{paymentNo}")
    public Result<Void> applyRefund(@PathVariable @NotBlank(message = "支付流水号不能为空") String paymentNo,
                                    @RequestParam BigDecimal refundAmount,
                                    @RequestParam(required = false) String refundReason,
                                    HttpServletRequest request) {
        Long userId = getUserIdFromToken(request);
        
        try {
            boolean success = paymentService.processRefund(userId, paymentNo, refundAmount, refundReason);
            return success ? Result.success("退款申请成功", (Void) null) : Result.error("退款申请失败");
        } catch (Exception e) {
            log.error("申请退款失败：{}", e.getMessage(), e);
            return Result.error("申请退款失败：" + e.getMessage());
        }
    }

    /**
     * 支付宝支付回调
     */
    @PostMapping("/callback/alipay")
    public String alipayCallback(@RequestBody String callbackData) {
        log.info("收到支付宝支付回调");
        
        try {
            boolean success = paymentService.handlePaymentCallback("ALIPAY", callbackData);
            return success ? "success" : "fail";
        } catch (Exception e) {
            log.error("处理支付宝回调失败", e);
            return "fail";
        }
    }

    /**
     * 微信支付回调
     */
    @PostMapping("/callback/wechat")
    public String wechatCallback(@RequestBody String callbackData) {
        log.info("收到微信支付回调");
        
        try {
            boolean success = paymentService.handlePaymentCallback("WECHAT", callbackData);
            if (success) {
                return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            } else {
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[处理失败]]></return_msg></xml>";
            }
        } catch (Exception e) {
            log.error("处理微信支付回调失败", e);
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[系统异常]]></return_msg></xml>";
        }
    }

    /**
     * 充值回调
     */
    @PostMapping("/callback/recharge/{paymentNo}")
    public Result<Void> rechargeCallback(@PathVariable @NotBlank(message = "支付流水号不能为空") String paymentNo) {
        try {
            boolean success = paymentService.processRechargeCallback(paymentNo);
            return success ? Result.success("充值回调处理成功", (Void) null) : Result.error("充值回调处理失败");
        } catch (Exception e) {
            log.error("处理充值回调失败：{}", e.getMessage(), e);
            return Result.error("处理充值回调失败：" + e.getMessage());
        }
    }

    /**
     * 从请求中获取用户ID
     */
    private Long getUserIdFromToken(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
            String token = bearerToken.substring(7);
            return jwtUtils.getUserIdFromToken(token);
        }
        throw new RuntimeException("Token不能为空");
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0];
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        
        return request.getRemoteAddr();
    }
}